iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
Software Development

戀戀 Elixir系列 第 28

二十八. Protocols

  • 分享至 

  • xImage
  •  

You're developing your own role-playing video game. In your game, there are characters and items. One of the many actions that you can do with an item is to make a character eat it.

Not all items are edible, and not all edible items have the same effects on the character. Some items, when eaten, turn into a different item (e.g. if you eat an apple, you are left with an apple core).

To allow for all that flexibility, you decided to create an Edible protocol that some of the items can implement.

1. Define edibility

Create the RPG.Edible protocol. The protocol has one function - eat. The eat function accepts an item and a character and returns a by-product and a character.

2. Make loaves of bread edible

Implement the RPG.Edible protocol for the RPG.LoafOfBread item. When eaten, a loaf of bread gives the character 5 health points and has no by-product.

3. Make mana potions edible

Implement the RPG.Edible protocol for the RPG.ManaPotion item. When eaten, a mana potion gives the character as many mana points as the potion's strength, and produces an empty bottle.

4. Make poisons edible

Implement the RPG.Edible protocol for the RPG.Poison item. When eaten, a poison takes away all the health points from the character, and produces an empty bottle.


https://exercism.org/tracks/elixir/exercises/bread-and-potions

defmodule RPG do
  @moduledoc """
  practice protocol
  """

  defmodule Character, do: defstruct(health: 100, mana: 0)

  defmodule LoafOfBread, do: defstruct([])

  defmodule ManaPotion, do: defstruct(strength: 10)

  defmodule Poison, do: defstruct([])

  defmodule EmptyBottle, do: defstruct([])

  defprotocol Edible do
    @spec eat(item :: struct(), character :: struct()) :: any
    def eat(item, character)
  end

  defimpl Edible, for: LoafOfBread do
    @spec eat(_ :: %LoafOfBread{}, character :: struct()) :: {nil, struct()}
    def eat(_, character) do
      {nil, %{character | health: character.health + 5}}
    end
  end

  defimpl Edible, for: ManaPotion do
    @spec eat(item :: %ManaPotion{}, character :: struct()) :: {%EmptyBottle{}, struct()}
    def eat(item, character) do
      {%EmptyBottle{}, %{character | mana: character.mana + item.strength}}
    end
  end

  defimpl Edible, for: Poison do
    @spec eat(_ :: %Poison{}, character :: struct()) :: {%EmptyBottle{}, struct()}
    def eat(_, character) do
      {%EmptyBottle{}, %{character | health: 0}}
    end
  end
end

上一篇
二十七. Agent
下一篇
二十九. Erlang Libraries & Randomness
系列文
戀戀 Elixir30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言